-- classes
--
-- Inheritance:
---------------
--
--          Gameelement
--              / \
--             /   \
--            /     \    
--        Skill    Character 
--                     /\          (many more)
--                 Hero  Enemy    /
--                            \-----bear
--                            |   \    
--                      redfish    greenfish
--       Weapon
-- (Container for skills)


dofile('testclasses/globalfunc.lua')

-- engine debug / ds
-- 1 = CONSOLEDEBUG 
-- 2 = DS
ENGINE = 2 



-- ==== DS things 

if ENGINE == 1 then
	SCREEN_HEIGHT = 200
	SCREEN_WIDTH = 200
end

if ENGINE == 2 then
  dofile('testclasses/engine_ds.lua')
end
-- ==== CONTROLS

controls = {}
controls['button1'] = '' --attack
controls['button2'] = '' --arrow
controls['button3'] = '' --fireball
controls['button4'] = ''
controls['button5'] = ''
controls['button6'] = ''
controls['left'] = ''    --movement
controls['right'] = ''   --movement
controls['up'] = ''      --movement 
controls['down'] = ''   --movement
controls['start'] = ''   --movement
controls['select'] = ''   --movement

-- == global values

directions = {'north', 'northeast', 'east', 'southeast', 'south', 'southwest', 'west', 'northwest'}

-- everything is added here with Gameelement:New()
gameelements = {} 
-- setmetatable(gameelements, {__mode = "v" })

-- collection for all enemies
enemies = {}
-- setmetatable(enemies, {__mode = "v" })

-- NOTE : the values of the table 'gameelements' should be weak. That means: if there is no other reference to this value (from other table), it will be removed by next garbage collection.

-- TODO: perfomrance issue: test local
local z = 'testlocal'
local zfunc = function () print('zfunc is everywhere') end

manareg = function (t)
	if 		t.manaregtime == nil or t.manaregtime < clock.second then
			t.manaregtime = clock.second + 1

	elseif	t.manaregtime == clock.second then
			t.mana = t.mana + t.manaregrate
			t.manaregtime = clock.second + 1
	end
	
	if t.manaregtime > 59 then t.manaregtime = 0 end
end


hpreg = function (t)
	if 		t.hpregtime == nil or t.hpregtime < clock.second then
			t.hpregtime = clock.second + 1
	elseif	t.hpregtime == clock.second then
			t.hp = t.hp + t.hpregrate
			t.hpregtime = clock.second + 1
	end
	if t.hpregtime > 59 then t.hpregtime = 0 end
  t.hp = t.hp + 10
end

--comment to states
--npc's general states :
-- 
--idle
--hunt
--dead (-> in run-part: checks time-to-life til object will be removed)
--
--the run-part of a state is for:
--movement,
--checking/triggering (is there a enemy?)

-- States
state_test = {
name = 'state_test',
starting = {function(t) print('test start function')end, function(t) t.currentstate.ttl = t.currentstate.ttl - 1 print(t.currentstate.ttl) end},
running = {function(t) print('test run function')end, function() print(z) end, zfunc},
ending = {function(t) print('test end function')end},
process = 'starting',
laststate = nil,
nextstate = nil,
ttl = 0, --TODO: needed?
temp = {} -- TODO: evt... weak table?
}


Gameelement = {
	x = 0, 
	y = 0,
	speed = 0,
	wid = 0, -- for collision area
	hig = 0,
	x_offset = 0, -- offset for collision area
	y_offset = 0,
	z_index = 1, -- on which layer it will be painted
	hp = 100, 
	dir = directions[math.random(1,8)], -- TODO: in radiant ?
	oht = {},
  name = 'a gameelement',
	image = {
  default = 'testclasses/resources/default.png'
  -- TODO: default value in paint ...
  -- those can be mirrored: southwest, west, northwest
  -- TODO:for paint function: if there is a path to a i.e. southwest paint it, else mirror
  },
	skills = {},
  -- TODO: no states for this abstract class 

  -- ===== the main functions ====
	-- new
	-- move =
	-- remove = 
	-- behit =
	-- collide = 
	-- behit =
	-- collide = 
	}

function runstate(x)
        local t = x				 
				for _, v in ipairs(t.currentstate[t.currentstate.process]) do
					v(t)
				end
end

function Gameelement:new(o)
  o = o or {} -- if no table is set , create an empty table
  setmetatable(o, self)
  self.__index = self
  -- TODO: TO_TEST if clone everything is better than metatables. TODO: functions till now not cloneable...
  -- o = deepclone(self)
  self.dir = directions[math.random(1,8)]
  self.x = math.random(0, SCREEN_WIDTH - self.wid)	
  self.y = math.random( 0, SCREEN_HEIGHT - self.hig)
  -- TODO: table.insert(gameelements,self)
  -- collectgarbage()

  return o 
  -- if there is no x or y set, randomize the startpoint
  -- TODO: randomize
  -- pseudocode
  -- ??? initalize clone startstate in currentstate ...
end

Character = Gameelement:new{ -- now, Character is just an Instance of Gameelement
hp = 100,
mana = 100, 
speed = 0, 
name = 'a character',
-- needed ?
projectiles = {}
}
-- -- -- -- -- -- -- -
-- -- OVERHEAD TEXT --
-- -- -- -- -- -- -- -
Gameelement.oht = {}

--Ein neuer OHT wird erstellt
function Character:newoht(text)
	Character.oht.status = 1
	Character.oht.text = text
	Character.oht.starttime = clock.second
end
	
--der OHT wird angezeigt
function Gameelement:runoht()
	if  clock.second - self.oht.starttime < 3 then 
	else
		self.oht.status = 0
	end
end
	
Character.attack = {}
Character.attack.range = 16
Character.attack.dmg = 17

Character.attack.wid = 5 -- Character.attack.range
Character.attack.hig = 5 -- Character.attack.range


function Character.attack.run()	
	if Character.dir == 'north' then 		
		Character.attack.x = Character.x 
		Character.attack.y = Character.y - (Character.attack.range/2)

	elseif Character.dir == 'northeast' then
		Character.attack.x = Character.x + (Character.wid/2)
		Character.attack.y = Character.y

	elseif Character.dir == 'east' then	
		Character.attack.x = Character.x
		Character.attack.y = Character.y + (Character.hig/2)								

	elseif Character.dir == 'southeast' then
		Character.attack.x = Character.x - (Character.attack.range/2)
		Character.attack.y = Character.y						

	elseif Character.dir == 'south' then
		Character.attack.x = Character.x + (Character.wid/2)
		Character.attack.y = Character.y - (Character.attack.range/2)						

	elseif Character.dir == 'southwest' then
		Character.attack.x = Character.x + (Character.wid/2)
		Character.attack.y = Character.y + (Character.hig/2)						

	elseif Character.dir == 'west' then
		Character.attack.x = Character.x - (Character.attack.range/2)
		Character.attack.y = Character.y - (Character.hig/2)						

	elseif Character.dir == 'northwest' then
		Character.attack.x = Character.x - (Character.attack.range/2)
		Character.attack.y = Character.y - (Character.attack.range/2)						
	end

	if #enemies > 0 then
		for i = 1, #enemies do
			if 	compare(Character.attack.x, Character.attack.y, Character.attack.wid, Character.attack.hig, enemies[i].x, enemies[i].y, enemies[i].wid, enemies[i].hig) == true
			then
				print("ola") 
								enemies[i]:damage(Character.attack.dmg)
								-- if enemies[i].hp <= 0 then
								print("delete "..i.." enemy")
								table.remove(enemies, i)
								collectgarbage()
								print(enemies[i])
								-- end
							end
						end	
					end
end

Skill = Gameelement:new{ -- now, Skill is just an Instance of Gameelement
damage = 100,
duration = 100,
name = 'a skill',
skills = {},
skills_progress = function () end
-- functions
-- run = function ()
--  koennteschwieriger werden, vor allem wenn ein skill viele andere skills ausloest, und so weiter, und so weiter , und so weiter, loop? loop protection?
}

function Skill:run()
	--testing
	print("does something")
end



-- function Projectile:new (o)
--   o = o or {} -- if no table is set , create an empty table
--   setmetatable(o, self)
--   self.__index = self
--   return o
-- end

-- ================== enemy import

-- -- -- -- -- -- -- -- -- -- -- --
-- -- ENEMIES -- -- -- -- -- -- -- -
-- -- -- -- -- -- -- -- -- -- -- --

Enemy = Character:new{speed = 2} -- now, Character is just an Instance of Gameelement
-- enemy states

Enemy.states = {
idle = {
				starting = {},
				running = {
function(t) if math.random(1,30) == 1 then t.dir = directions[math.random(1,8)] end end,
-- search function for enemy's idle state
function (t) -- checks if the monster is to hunt the hero
	if compare( (t.x - t.searchrange), (t.y - t.searchrange), (t.searchrange * 2 + t.wid) , (t.searchrange * 2 + t.hig), hero.x,hero.y, hero.wid, hero.hig) == true
	then 	
    t.currentstate = t.states.hunt
    -- TODO: instead of line above use a changestate function, which clears tmp data and sets process of old state to 'starting'
    runstate(t)
	end	
end
},
				ending = {},
name = 'idle'
},
hunt = { 
  name = 'hunt',
	starting = {},
	running = {
		function(t)
			if compare( (t.x - t.attackrange), (t.y - t.attackrange), (t.wid  + t.attackrange) , (t.attackrange + t.hig), hero.x, hero.y, hero.wid, hero.hig) == true then 
  		t.currentstate = t.states.attack
			runstate(t)
  		-- TODO: insert changestatefunction
  		else
			if	t.x == hero.x and
				t.y > hero.y then t.dir = 'north'
			elseif 	t.x < hero.x and
				t.y == hero.y then t.dir = 'northeast'
			elseif 	t.x == hero.x and
				t.y < hero.y then t.dir = 'east'
			elseif 	t.x > hero.x and
				t.y == hero.y then t.dir = 'southeast'
			elseif 	t.x < hero.x and
				t.y > hero.y then t.dir = 'south'
			elseif 	t.x < hero.x and
				t.y < hero.y then t.dir = 'southwest'
			elseif 	t.x > hero.x and
				t.y < hero.y then t.dir = 'west'
			elseif 	t.x > hero.x and
				t.y > hero.y then t.dir = 'northwest'
			end		
		end
	end
	},
	ending = {
	},
  process = 'running'
	},
	attack = { 
  name = 'attack',
	starting = {},
	running = {
    function(t) 
    	-- TODO: check if in range. if not change state to hunt
      -- if self.attacklimit < clock.second then
    		-- self.attacklimit = clock.second + 1 * self.attackrate
    		--if self.attackrate > 59 then self.attackrate = self.attackrate - 60 end
    		hero.hp = hero.hp - 2 
    if ENGINE == 1 then print('attack! baammm!') end
end 
-- end
  },
	ending = {
	},
  process = 'running'
	}
}

Enemy.currentstate = Enemy.states.idle
Enemy.currentstate.process = 'running'
Enemy.x = 0
Enemy.y = 0
Enemy.speed = 1
Enemy.experience = 0
Enemy.dmg = 0
Enemy.attackrange = 0
Enemy.attackrate = 0
Enemy.attacklimit = 0
Enemy.hp = 10
Enemy.dir = directions[math.random(1,8)]
Enemy.exp = 10
Enemy.wid = 5
Enemy.hig = 5
Enemy.attacklimit = 0
Enemy.oht = {}
Enemy.oht.x = 0
Enemy.oht.y = 0
Enemy.oht.text= 'oht text'
Enemy.oht.starttime = 0
Enemy.oht.status = 0

-- handels the movement of the every gameelement, independent of state
-- calculates the new X|Y coordinates
function move(x)
  local t = x 
	if t.dir == 'north' then t.y = t.y - t.speed
	elseif t.dir == 'east' then t.x = t.x + t.speed
	elseif t.dir == 'south' then t.y = t.y + t.speed
	elseif t.dir == 'west' then 	t.x = t.x - t.speed
	elseif t.dir == 'northeast' then 	t.x = t.x + t.speed
		t.y = t.y- t.speed
	elseif t.dir == 'southeast' then 	t.x = t.x + t.speed
		t.y = t.y+ t.speed
	elseif t.dir == 'southwest' then 	t.x = t.x - t.speed
		t.y = t.y+ t.speed
	elseif t.dir == 'northwest' then 	t.x = t.x - t.speed
		t.y = t.y- t.speed
	end
-- avoids that an enemy can leave the screen
	if t.x < 0 then t.x = 0 end
	if t.x + t.wid > SCREEN_WIDTH then t.x = SCREEN_WIDTH - t.wid end
	if t.y < 0 then t.y = 0 end
	if t.y + t.hig > SCREEN_HEIGHT then t.y = SCREEN_HEIGHT - t.hig end
end

--  TODO: -2 ??? dynamic damage ???
function Gameelement:damage(dmg) -- this function is tho deal damage to a monster
	self.hp = self.hp - dmg
	print("hp:\t"..self.hp..'\tdmg\t'..dmg)
	self:newoht(dmg)
	if self.hp < 1 then self:destroy() end
end

function Gameelement:destroy() --if monster dies, this functions delet the monster and gives  exp to the hero
        hero.exp = hero.exp + self.exp
	print(self)
	print('destroy!')
	self = nil -- set table to nil
	-- TODO: collect the garbage?
  collectgarbage()
	print(self)
	-- return self
end

-- ================= MONSTERS

-- testing 
Fish = Enemy:new{
	experiencepoints = 10,
	searchrange = 50,						
	name = 'a Fish',
  wid = 17, 							
	hig = 17,							
	speed = 1,							
	dmg = 5,						
	attackrange = 3,
	attackrate = 0.5,
	image = {
		default = 'testclasses/resources/greenfish.png',
	}
}


redfish = Fish:new()
greenfish = Fish:new{
	name = 'a green fish',
	speed = 1,
  image = {
		default = 'testclasses/resources/default.png'
	}
}
-- ================= HERO

hero = Character:new{}
hero.dir = 'south'
-- TODO: Waffen!
hero.weapon = DefaultSword
hero.mana = 50
hero.manamax = 100
hero.manaregrate = 1
hero.hp = 50
hero.exp = 0
hero.level = 1
hero.hpmax = 100 
hero.hpregrate = 1 
hero.name = 'THE hero'
hero.image = {
default = 'testclasses/resources/default.png'
}
hero.sprite = { 
		image = "testclasses/resources/char.png",
		wid = 24,
		hig = 32,
  -- animations for cardinal directions
    default = {
	  	animation = {6,7,8,7},
	  	duration = 300
	  },
    north = {
	  	animation = {0,1,2,1},
	  	duration = 300
	  },
    northeast = {
	  	animation = {0,1,2,1},
	  	duration = 300
	  },
    east = {
	  	animation = {3,4,5,4},
	  	duration = 300
	  },
    southeast = {
	  	animation = {6,7,8,7},
	  	duration = 300
	  },
    south = {
	  	animation = {6,7,8,7},
	  	duration = 300
	  },
    southwest = {
	  	animation = {6,7,8,7},
	  	duration = 300
	  },
    west = {
	  	animation = {9,10,11,10},
	  	duration = 300
	  },
    northwest = {
	  	animation = {0,1,2,1},
	  	duration = 300
	  }
  }

hero.states = {control = {
	name = 'control',
  starting = {},
	running = {
-- -- -- -- -- -- -- --
-- -- STATUSCHECK -- --
-- -- -- -- -- -- -- --
function (t)--hero.statuscheck() -- basic, experience, health, mana, oht status check. nearly in every state avaible
 if t.hp <= 0 then t.currentstate = t.states['dead'] end -- TODO: changestate function
 if t.oht.status == 1 then t.oht.run() end
 if t.mana < t.manamax then manareg(t)end
 if t.hp < t.hpmax then hpreg(t)end
 if t.exp > t.level * 20 then
	t.level = t.level + 1
	t.hp = t.hpmax
	t.mana = t.manamax
	t.skp = t.skp + 5
	t:newoht("Level up!!  "..t.level)
 end
end,

-- -- -- -- -- -- -- --
-- -- CONTROLS -- -- -- 
-- -- -- -- -- -- -- --
function(t)
  if controls.button1 == 'pressed' then -- TODO: controller basic to do ... !!
	  if t.dir == 'north' then 		
	  	t.attack.x = t.x 
	  	t.attack.y = t.y - (t.attack.range/2)

	  elseif t.dir == 'northeast' then
	  	t.attack.x = t.x + (t.wid/2)
	  	t.attack.y = t.y

	  elseif t.dir == 'east' then	
	  	t.attack.x = t.x
	  	t.attack.y = t.y + (t.hig/2)								

	  elseif t.dir == 'southeast' then
	  	t.attack.x = t.x - (t.attack.range/2)
	  	t.attack.y = t.y						

	  elseif t.dir == 'south' then
	  	t.attack.x = t.x + (t.wid/2)
	  	t.attack.y = t.y - (t.attack.range/2)						

	  elseif t.dir == 'southwest' then
	  	t.attack.x = t.x + (t.wid/2)
	  	t.attack.y = t.y + (t.hig/2)						

	  elseif t.dir == 'west' then
	  	t.attack.x = t.x - (t.attack.range/2)
	  	t.attack.y = t.y - (t.hig/2)						

	  elseif t.dir == 'northwest' then
	  	t.attack.x = t.x - (t.attack.range/2)
	  	t.attack.y = t.y - (t.attack.range/2)						
	  end

	  if #enemies > 0 then
	  	for i = 1, #enemies do
	  		if 	compare(t.attack.x, t.attack.y, t.attack.wid, t.attack.hig, enemies[i].x, enemies[i].y, enemies[i].wid, enemies[i].hig) == true
	  		then
	  			print("ola") 
	  			enemies[i]:damage(t.attack.dmg)
	  			-- if enemies[i].hp <= 0 then
	  			print("delete "..i.." enemy")
	  			table.remove(enemies, i)
	  			collectgarbage()
	  			print(enemies[i])
	  			-- end
	  		end
	  	end	
	  end
  end
end,
function (t)
	if controls.button5 == 'pressed'
	then game.status = 1 
	end
end,
function (t)
	if controls.button6 == 'pressed'
	then game.status = 2 
	end
end,

-- TODO: define arrow shot function in controls.func.button1 or similar..
-- function (t) -- shot arrow
--   PSEUOCODE 
--   if controls.button2 == 'pressed' and enough arrows then
--     Arrow:new{dir = t.dir, x = t.x - (t.wid / 2) -(self.wid / 2), y= t.y - (t.hig / 2) - (self.hig / 2)}
	  	-- TODO: remove max possible shoots ?
      -- t.shotmax = t.shotmax + 1
	  	-- t.mana = t.mana - t.shot.cost

	  -- else
	  -- 	t.oht.new("Not enough mana!!!")
	  --end
--     --removes arrow from arrows of hero
--     t.shotmax = t.shotmax - 1
--   end
-- end,
-- function (t) -- shot fireball
-- NOTE: look above, same as arrows...
-- end

function (t) --hero.move.up()
  if controls.up == 'held' then
	t.dir = 'north'
	t.y = t.y - 10
  end
end,

function (t)
  if controls.right == 'held' and controls.up == 'held' then
	t.dir = 'northeast'
	t.x = t.x + 10
	t.y = t.y - 10
  end
end,

function (t)
  if controls.right == 'held' then
	t.dir = 'east'
	t.x = t.x + 10
  end
end,

function (t)
  if controls.right == 'held' and controls.down == 'held'  then
	t.dir = 'southeast'
	t.x = t.x + 10
	t.y = t.y + 10
  end
end,

function (t)
  if controls.down == 'held' then
	t.dir = 'south'
	t.y = t.y + 10
  end
end,

function (t)
  if controls.down == 'held' and controls.left == 'held'  then
	t.dir = 'southwest'
	t.x = t.x - 10
	t.y = t.y + 10
  end
end,

function (t)
  if controls.left == 'held' then
	t.dir = 'west'
	t.x = t.x - 10
  end
end,	

function (t)
  if controls.left == 'held' and controls.up == 'held' then
	t.dir = 'northwest'
	t.x = t.x - 10
	t.y = t.y - 10
  end
end
},
  ending = {},
  process = 'running'
	},
dead = {
name = 'dead',
starting = {},
running = {
function ()
-- TODO : new oht ...
		if ENGINE == 1 then 	
			print("gstorbe")
		else
			screen.print(SCREEN_DOWN, 50,50, "Du bis gestorben") -- Falls held tot ist erscheint diese Botschaft
		end
end
},
ending = {},
process = 'running'
}
}

function hero.load()
	hero.save = INI.load("hero/hero.ini")
	-- Info
	hero.name = hero.save.info.name
	hero.class = hero.save.info.class
	
	-- Stats
	hero.skp = hero.save.skillpoints.freeskillpoints * 1-- Unused skillpoints
	hero.str = hero.save.skillpoints.strenght
	hero.agi = hero.save.skillpoints.agility
	hero.int = hero.save.skillpoints.inteligence
	hero.dex = hero.save.skillpoints.dexterity 
	
	-- Hero Status
	hero.level = hero.save.status.level * 1
	hero.exp = hero.save.status.experiencepoints * 1
	hero.hp = hero.save.status.life * 1
	hero.hpmax = hero.save.status.lifemax * 1
	hero.hpregrate = hero.save.status.lifereg * 1
	hero.mana = hero.save.status.mana * 1
	hero.manamax = hero.save.status.manamax * 1
	hero.manaregrate = hero.save.status.manareg * 1
	hero.speed =  hero.save.status.speed * 1
	
	hero.arrows = hero.save.status.arrows * 1
	
	hero.dead = 0
	
	-- Heros measure
	hero.x = 5
	hero.y = 50
	hero.wid = 24
	hero.hig = 32
	
	-- -- -- -- -- -- -- --
	-- -- ITEMS -- -- -- -
	-- -- -- -- -- -- -- --
	hero.items = {}
	hero.items.head= hero.save.items.head
	hero.items.handleft = hero.save.items.handleft
	hero.items.handright = hero.save.items.handright
	hero.items.body = hero.save.items.body
	hero.items.legs = hero.save.items.legs
	hero.items.feeds = hero.save.items.feeds
end

function hero.savegame()
	-- Info
	hero.save["info"]["name"] = "hero.name"
	hero.save["info"]["class"] = "hero.class"
	
	-- Status
	hero.save["status"]["level"] = "hero.level"
	hero.save["status"]["life"] = "hero.hp"
	hero.save["status"]["lifemax"] = "hero.hpmax"
	hero.save["status"]["mana"] = "hero.mana"
	hero.save["status"]["manareg"] = "hero.manareg"
	hero.save["status"]["manamax"] = "hero.manamax"
	hero.save["status"]["speed"] = "hero.speed"
	hero.save["status"]["speed"] = "hero.arrows"
	INI.save("hero.INI", hero.save)
end 

hero.shot = {}
hero.shot.wid = 9
hero.shot.hig = 9
hero.shotx = {}
hero.shoty = {}
hero.shotdir = {}
hero.shotmax = 0
hero.shot.shoot = 0
hero.shotkill = 0

-- -- -- -- -- -- -- --
-- -- Arrow -- -- -- --
-- -- -- -- -- -- -- --

Arrow = Gameelement:new{
  cost = 0,
  damage = 13,
  speed = 2
}
Arrow.image = {
default = 'testclasses/resources/onearrow.png'
}
Arrow.states = { flying = {
starting = {},
running = {function (t)
	if t.x + t.wid < 0 or t.y < 0 or t.y +  t.hig > SCREEN_HEIGHT or tx > SCREEN_WIDTH then 	t:destroy()	end end,
-- TODO: collid function! make it global! like function collide(something, anythin)
function (t)
		if #enemies > 0 then
			for i = 1, #enemies do
				if 	t.x + t.wid > enemies[i].x and 
					t.x < enemies[i].x + enemies[i].wid and 
					t.y + t.hig > enemies[i].y  and 
					t.y < enemies[i].y + enemies[i].hig
				then 	enemies[i]:damage(t.damage) -- TODO: damage ? dmg?
						t:destroy()
					  table.remove(enemies, i)
						break
				end
			end		
		end
end
},
ending = {},
process = 'running'
},
-- when target meets arrow
intarget = {
name = 'intarget'
}
}

-- -- -- -- -- -- -- --
-- -- Fireball -- -- --
-- -- -- -- -- -- -- --
Fireball = Arrow:new{ -- TODO: Skill? --Skill:new{
speed = 1.5,
cost = 10,
damage = 15,
wid = 20,
hig = 20,
image = {
	default = "testclasses/resources/onefireball.png"	
}
}

-- -- -- -- -- -- --
-- -- MENU  -- -- --
-- -- -- -- -- -- --
-- TODO: cant load 'image' hooo?

-- 'sp' is the abbreviation of skillpoints

menu = {}

menu.sp = {}

menu.sp.image = "testclasses/resources/sps.png"
if ENGINE == 1 then
menu.sp.x = 4
menu.sp.y = 4
menu.sp.wid = 4
menu.sp.hig = 4
elseif ENGINE == 2 then
--menu.sp.x = (SCREEN_WIDTH - Image.width(menu.sp.image))/ 2
--menu.sp.y = (SCREEN_HEIGHT - Image.height(menu.sp.image))/ 2
--menu.sp.wid = Image.height(menu.sp.image)
--menu.sp.hig = Image.width(menu.sp.image)
end

function menu.sp.screen() -- Function zum anzeigen des Menus,
	screen.blit (SCREEN_DOWN, menu.sp.x, menu.sp.y, spimg)
	screen.print(SCREEN_DOWN, menu.sp.x,menu.sp.y, hero.skp)
	screen.print(SCREEN_DOWN, menu.sp.x +104,menu.sp.y +11, hero.str)
	screen.print(SCREEN_DOWN, menu.sp.x +104,menu.sp.y +28, hero.agi)
	screen.print(SCREEN_DOWN, menu.sp.x +104,menu.sp.y +46, hero.int)
	screen.print(SCREEN_DOWN,menu.sp.x + 104,menu.sp.y +64, hero.dex)
	if Keys.newPress.B then game.status = 1 end
	if hero.skp > 0 then menu.sp.control() end

end

function menu.sp.control()
	if Stylus.released then
	sty = {}
	sty.x = Stylus.X
	sty.y = Stylus.Y
		if sty.x > menu.sp.x + 132 and sty.x < menu.sp.x + 144 then
			if sty.y > menu.sp.y + 12 and sty.y < menu.sp.y + 12 then hero.str  = hero.str + 1 hero.skp = hero.skp -1 end
			if sty.y > menu.sp.y + 30 and sty.y < menu.sp.y + 42 then hero.agi  = hero.agi + 1 hero.skp = hero.skp -1 end
			if sty.y > menu.sp.y + 48 and sty.y < menu.sp.y + 50 then hero.int  = hero.int + 1 hero.skp = hero.skp -1 end
			if sty.y > menu.sp.y + 67 and sty.y < menu.sp.y + 79 then hero.dex  = hero.dex + 1 hero.skp = hero.skp -1 end
			sty.x = 0
			sty.y = 0			
		end
	end
end

-- ================= MAIN File 


game = {}
game.start = {}
game.start.round = {}
game.round = 0
game.status = 1
 
if ENGINE == 1 then
-- do nothing
elseif ENGINE == 2 then
-- TODO: dont load things...
--hero.load()
end
-- -- -- -- -- -- -- -- -- --
-- -- Rounds -- -- -- -- -- ======> only for testing the game. Will be deleted.
-- -- -- -- -- -- -- -- -- --

function game.rounds()
  if #gameelements < 2 then 
    game.round = game.round + 1 
    game.start.round(game.round)
  end
end

function game.start.round(max)
	for i= 1, max do	
		table.insert(gameelements, redfish:new())
	end
end

-- sprites / images are loaded at gamestart
paintable_objects = {Enemy, Fish, redfish, greenfish, hero}

-- -- -- -- -- -- -- -- -- --
-- -- MAINLOOP -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- 

-- TODO:
if ENGINE == 1 then
  clock = {}
  clock.second = os.time()
end

function paint_console (t)
	if t.currentstate.sprite then
		print('x: '..t.x..' y: '..t.y..' -> '..t.currentstate.sprite.image)
	elseif t.currentstate.image then 
		print('x: '..t.x..' y: '..t.y..' -> '..t.currentstate.image.default)
	elseif t.sprite then 
		print('x: '..t.x..' y: '..t.y..' -> sprite: '..t.sprite.image)
	elseif t.image then 
		print('x: '..t.x..' y: '..t.y..' -> image:'..t.image.default)
	end
end


-- load engine (ds, consoledebug)
function debugconsole ()
-- TODO: 'run' is 1.runcurrentstate 2. move 3. paint 4. paint ~'oht' 5. changestate if available

  clock.second = os.time()
  if game.status == 1 then -- game running
		-- logical part
		game.rounds()
    for i=1, #gameelements do
		  gameelements[i]:runstate()
		  gameelements[i]:move()
      paint_console(gameelements[i])
    end

    -- paint part
    -- 1.background, 2. z-index == 1, 3. hero, 4. z-index == 2 
    -- 5. gameelments, 6. clouds etc, last: 'oht's
	  print('background')
	  
		--	screen.blit(SCREEN_DOWN,enemies[_i].x,enemies[_i].y, enemies[_i].sprite)
		-- if enemies[_i].oht.status == 1 then enemies[_i].oht:run() end
 
	elseif game.status == 2 then print('gamestatus == 2') -- game stopped
	end
	print(hero.hp)
	print(hero.mana)
	print(hero.level)
end

table.insert(gameelements, hero)
hero.currentstate = hero.states.control

-- TODO: remove soon!
if ENGINE == 1 then -- do nothing
-- TODO: DEBUG with debugconsole()

elseif ENGINE == 2 then 
  imageload_ds()
  controlsupdate_ds()

local gms = gameelements
local background = Image.load("testclasses/resources/background.png", VRAM)
local pds = paint_ds
local m = move
local rs = runstate
while not false do --controls.start == 'pressed' do
-- TODO: 'run' is 1.runcurrentstate 2. move 3. paint 4. paint ~'oht' 5. changestate if available

  controlsupdate_ds()
  startDrawing()
	clock.run()
	if game.status == 1  then -- game running
		-- 1. ### logical part
    -- 2. ### paint part
    --        1.background, 2. z-index == 1, 3. hero, 4. z-index == 3 
    --        5. gameelements, 6. clouds etc, last: 'oht's
		game.rounds()
    if controls.button1 == 'pressed' then 
		  table.insert(gms, redfish:new())
		  table.insert(gms, greenfish:new())
		end
    if controls.button2 == 'held' then 
      local r = redfish:new()
		  table.insert(gms, r)
      --TODO: test with rawset(table, key, value)
			if ENGINE == 2 then imageloadevery_ds(r) end
      local g = greenfish:new()
		  table.insert(gms, g)
      if ENGINE == 2 then imageloadevery_ds(g) end
		end


    paint_ds_layer1() --background	
    
    -- ############ control test
    for _,v  in ipairs(gms) do
      local ge = v
		  m(ge)
		  rs(ge)
      -- TODO: oht stuff: gms[i]:runoht()
    --if math.random(0,5) == 1 then
		  pds(ge)
    -- testpaint()
    --end
     --TODO: oht stuff: paint_oht(gameelements[i])

    -- TODO replace ~arrow~ run() with state functions and move
    --
    --      if hero.shotdir[shi] == 1 then shotdegree = 360 else shotdegree = ((hero.shotdir[shi] - 1) * 45) end
    --      Image.rotateDegree(arrowspr, shotdegree)
    --      screen.blit(SCREEN_DOWN, hero.shotx[shi], hero.shoty[shi],arrowspr)
    --	end	

		end
    paint_ds_layer3() --debug 
	elseif game.status == 2 then -- game stopped
		--menu.sp.screen()
	end
stopDrawing()
end



background = nil
spimg = nil

if ENGINE == 1 then
-- do nothing
elseif ENGINE == 2 then hero.savegame() end
end
